package com.education.auth.controller;

import com.education.auth.aspectannotation.BusinessDiary;
import com.education.auth.client.UserClient;
import com.education.auth.client.WisdomFeign;
import com.education.auth.config.JwtProperties;
import com.education.auth.entity.UserInfo;
import com.education.auth.service.AuthService;
import com.education.auth.utlis.JwtUtils;
import com.education.common.pojo.SysUserOther;
import com.education.common.utils.ApiReturnObject;
import com.education.common.utils.CookieUtils;
import com.education.user.pojo.User;
import com.education.user.pojo.UserVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;

/**
 * @author: ly
 * @create: 2018-07-07 17:59
 **/
@RestController
@EnableConfigurationProperties(JwtProperties.class)
@Api(tags = {"用户登陆  获取token"})
public class AuthController {

    @Autowired
    private AuthService authService;

    @Autowired
    private JwtProperties prop;

    @Autowired
    private UserClient userClient;

    @Autowired
    private WisdomFeign wisdomFeign;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 查找标签列表
     */
    @ApiOperation(value = "登陆-获取token-PC 管理员登录 教师和教务无权限登录", httpMethod = "POST")
    @BusinessDiary(methodUrl = "/accredit", record = "智慧云课堂管理端用户登录", opeTypeName = "登录")
    @PostMapping("/accredit")
    public ApiReturnObject accreditLogin(@RequestBody User user, HttpServletRequest req, HttpServletResponse resp) {
        // 登录
        UserVO vo = this.authService.login(user.getSysPhone(), user.getSysPassword());
        // 判断token
        if (vo != null) {
            if (vo.getCode() != null && vo.getCode() == 501) {
                return new ApiReturnObject("300", "该账号无权限登录此平台", null);
            }
            if (vo.getCode() != null && vo.getCode() == 500) {
                return new ApiReturnObject("300", "该账号已被停用", null);
            }
            if (StringUtils.isBlank(vo.getToken())) {
                // 返回401
                return new ApiReturnObject("401", "登录失败", null);
            }
            if (vo.getCode() != null && vo.getCode() == 600) return new ApiReturnObject("401", "账号已过期", null);
            // 写入cookie中
            CookieUtils.setCookie(req, resp, prop.getCookieName(), vo.getToken(), true);
            // 返回200 用户信息以及菜单列表
            HashMap<String, Object> map = new HashMap<>();
            //写入用户信息
            map.put("user", vo);
            //写入菜单列表
            ApiReturnObject sysMenus = userClient.queryMenuListByUserId(vo.getId().intValue());
            map.put("menuList", sysMenus.getReturnObject());
            return new ApiReturnObject("200", "登录成功", map);
        }
        return new ApiReturnObject("300", "用户名和密码输入有误", null);
    }

    @ApiOperation(value = "登陆-获取token-PC 教师登录 管理员无权限登录", httpMethod = "POST")
    @BusinessDiary(methodUrl = "/accreditTea", record = "智慧云课堂用户登录", opeTypeName = "登录")
    @PostMapping("accreditTea")
    public ApiReturnObject accreditTea(@RequestBody User user, HttpServletRequest req, HttpServletResponse resp) {
        //判断当前用户是否存在
        boolean exit = authService.extisUser(user.getSysPhone());

        //当前用户不存在
        if (!exit) {
            return new ApiReturnObject("500", "当前用户不存在", null);
        }

        //存在就去登陆限制表查询，是否满足登陆条件
        boolean satisfyLogin = authService.satisfyLogin(user);

        if (!satisfyLogin) {
            return new ApiReturnObject("500", "登陆次数过多，请稍后重试", null);
        }

        // 登录
        UserVO vo = this.authService.loginTea(user.getSysPhone(), user.getSysPassword());
        // 判断token
        if (vo != null) {
            if (vo.getCode() != null && vo.getCode() == 501) {
                return new ApiReturnObject("300", "该账号无权限登录此平台", null);
            }
            if (vo.getCode() != null && vo.getCode() == 500) {
                return new ApiReturnObject("300", "该账号已被停用", null);
            }
            if (StringUtils.isBlank(vo.getToken())) {
                // 返回401
                return new ApiReturnObject("401", "登录失败", null);
            }
            if (vo.getCode() != null && vo.getCode() == 600) return new ApiReturnObject("401", "账号已过期", null);
            // 写入cookie中
            CookieUtils.setCookie(req, resp, prop.getCookieName(), vo.getToken(), true);
            // 返回200 用户信息以及菜单列表
            HashMap<String, Object> map = new HashMap<>();
            //写入用户信息
            map.put("user", vo);
            //写入菜单列表
            ApiReturnObject sysMenus = userClient.queryMenuListByUserId(vo.getId().intValue());
            map.put("menuList", sysMenus.getReturnObject());
            return new ApiReturnObject("200", "登录成功", map);
        }
        return new ApiReturnObject("300", "用户名和密码输入有误", null);
    }

    @ApiOperation(value = "登陆-获取token-PC 今软平台进行登录", httpMethod = "POST")
    @BusinessDiary(methodUrl = "/accreditJinRan", record = "今软平台用户登录", opeTypeName = "登录")
    @PostMapping("/accreditJinRan")
    public ApiReturnObject accreditJinRan(@RequestBody User user, HttpServletRequest req, HttpServletResponse resp) {
        // 登录
        UserVO vo = this.authService.loginJinRan(user.getSysPhone(), user.getSysPassword());
        // 判断token
        if (vo != null) {
            if (vo.getCode() != null && vo.getCode() == 501) {
                return new ApiReturnObject("300", "该账号无权限登录此平台", null);
            }
            if (vo.getCode() != null && vo.getCode() == 500) {
                return new ApiReturnObject("300", "该账号已被停用", null);
            }
            if (StringUtils.isBlank(vo.getToken())) {
                // 返回401
                return new ApiReturnObject("401", "登录失败", null);
            }
            if (vo.getCode() != null && vo.getCode() == 600) return new ApiReturnObject("401", "账号已过期", null);
            // 写入cookie中
            CookieUtils.setCookie(req, resp, prop.getCookieName(), vo.getToken(), true);
            // 返回200 用户信息以及菜单列表
            HashMap<String, Object> map = new HashMap<>();
            //写入用户信息
            map.put("user", vo);
            //写入菜单列表
            ApiReturnObject sysMenus = userClient.queryMenuListByUserId(vo.getId().intValue());
            map.put("menuList", sysMenus.getReturnObject());
            return new ApiReturnObject("200", "登录成功", map);
        }
        return new ApiReturnObject("300", "用户名和密码输入有误", null);
    }

    @ApiOperation(value = "登陆-获取token-APP-今饭碗教师app", httpMethod = "POST")
    @BusinessDiary(methodUrl = "/app/accredit", record = "今饭碗教师app登录", opeTypeName = "登录")
    @PostMapping("app/accredit")
    public ApiReturnObject login1(String username, String password, HttpServletRequest req, HttpServletResponse resp) {
        //登录
        HashMap<String, Object> map = new HashMap<>(3);
        UserVO vo = this.authService.login1(username, password);
        if (vo == null) {
            return new ApiReturnObject("203", "账号未注册", map);
        }
        if (vo.getSysState() == 1) {
            return new ApiReturnObject("203", "该账号已被停用", map);
        }
        // 判断token
        if (vo != null) {
            if (StringUtils.isBlank(vo.getToken())) {
                // 返回401
                return new ApiReturnObject("401", "登录失败", map);
            }
            if (vo.getCode() != null && vo.getCode() == 600) {
                return new ApiReturnObject("401", "账号已过期", map);
            }
            // 写入cookie中
            CookieUtils.setCookie(req, resp, prop.getCookieName(), vo.getToken(), true);
            // 返回200
            return new ApiReturnObject("200", "登录成功", vo);
        }
        return new ApiReturnObject("300", "用户名和密码输入有误", map);
    }

    @GetMapping("verify")
    public ResponseEntity<UserInfo> verify(
            @CookieValue("TOKEN") String token,
            HttpServletRequest req, HttpServletResponse resp) {
        // 解析token
        try {
            // 校验token
            UserInfo info = JwtUtils.getInfoFromToken(token, prop.getPublicKey());
            // 刷新token
            String newToken = JwtUtils.generateToken(info, prop.getPrivateKey(), prop.getExpire());
            // 写入cookie
            CookieUtils.setCookie(req, resp, prop.getCookieName(), newToken, true);
            return ResponseEntity.ok(info);
        } catch (Exception e) {
            // 返回401
            return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
        }
    }

    //获取token
    @GetMapping("/getToken")
    public String getToken(Integer userId) {
        return authService.getToken(userId);
    }


    /**
     * 获取到token 存到redis中 将键返回给前端
     */
    @GetMapping("/saveToken")
    public ApiReturnObject saveToken(String token, Integer userId) {
        //将userId 进行加密
        Long l = userId + System.currentTimeMillis();
        //将验证码保存起来供进行对比
        RBucket<Object> bucket = redissonClient.getBucket(l.toString());
        bucket.set(token);
        //保存成功
        return new ApiReturnObject("200", "执行成功", l);
    }


    /**
     * token 合法 实现自动跳转
     */
    @ApiOperation(value = "实现自动跳转", httpMethod = "GET")
//    @GetMapping("voluntarilyLogin/{id}")
    @GetMapping("/voluntarilyLogin")
//    public ApiReturnObject login(@PathVariable("id") String l) {
    public ApiReturnObject login(String token) {
//        RBucket<String> bucket = redissonClient.getBucket(l);
//        String token = bucket.get();

        SysUserOther sysUserOther = new SysUserOther();
        //解析token
        try {
            UserInfo userInfo = JwtUtils.getInfoFromToken(token, prop.getPublicKey());
            sysUserOther = userClient.selectOneById(userInfo.getId().intValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (sysUserOther.getSysPhone() != null && !"".equals(sysUserOther.getSysPhone()) && sysUserOther.getSysPassword() != null && !"".equals(sysUserOther.getSysPassword())) {
            // 登录
            UserVO vo = this.authService.login2(sysUserOther.getSysPhone(), sysUserOther.getSysPassword());
            // 判断token
            if (vo != null) {
                if (vo.getCode() != null && vo.getCode() == 501) {
                    return new ApiReturnObject("300", "该账号无权限登录此平台", null);
                }
                if (vo.getCode() != null && vo.getCode() == 500) {
                    return new ApiReturnObject("300", "该账号已被停用", null);
                }
                if (StringUtils.isBlank(vo.getToken())) {
                    // 返回401
                    return new ApiReturnObject("401", "登录失败", null);
                }
                // 写入cookie中
                //CookieUtils.setCookie(req, resp, prop.getCookieName(), vo.getToken(), true);
                // 返回200 用户信息以及菜单列表
                HashMap<String, Object> map = new HashMap<>();
                //写入用户信息
                map.put("user", vo);
                //写入菜单列表
                ApiReturnObject sysMenus = userClient.queryMenuListByUserId(vo.getId().intValue());
                map.put("menuList", sysMenus.getReturnObject());
                //推送消息
                // Integer count = wisdomFeign.selectCount(vo.getId().toString());
                return new ApiReturnObject("200", "登录成功", map);
            }
        }
        return new ApiReturnObject("300", "token失效，请重新登录", null);
    }
}
